package study.JavaAdvanced;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

/**
 * date：2025.10.13
 * title：LinkedList 链表
 * author:fzy
 */

//666链表都来了
//链表就是在一个节点存储下一个节点的地址，前后相连
//单向链表，双向链表，单向链表每一个节点存储值和下一个节点的地址，双向多了上一个节点的地址
//与ArrayList相比，链表的增删效率高，但是查找修改效率低
//使用场景
//1.频繁访问元素时，只需要对首位进行操作时---ArrayList
//2.需要迭代访问数组时，需要频繁的在中间进行元素添加删除等操作时---LinkedList
    /*
    LinkList特有功能
    void addFirst(E e)：在开头插入指定元素
    void addLast(E e):在末尾...
    E getFirst():...
    E getLast():...
    E removeFirst()
    E removeLast()
     */
public class Java_3 {
    public static void main(String[] arg) {
        Integer[] valueArr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        LinkedListClass linkedSite = LinkedListClass.getIns();
        LinkedListClass reverseLinkedSite = LinkedListClass.getIns();
        System.out.println(LinkedListClass.instanceArr.size());
        for (Integer i : valueArr) {
            linkedSite.addToLinkedList(i);
            reverseLinkedSite.addToLinkedList(i, true);
        }
        LinkedListClass.printIns();
        LinkedListClass.clearIns();
    }
}

//这里按照豆包的建议进行代码优化，问题主要以下几点
//1.内存泄露一刀切，如果说直接将实例地址置为null，当下一次使用getIns的时候就会抛出空地址异常，不可取
//2.getSite方法破坏封装性，哈哈这个太抽象了，你都已经把链表私有化了你为啥还要把他返回呢，那你封装的这些增删改查不就是坨了，豆包的修改方法为返回链表的映射，如toArray方法返回
//3. 异常处理：暂时不处理

class LinkedListClass {
    //创建链表实例
    private LinkedList<Integer> site = new LinkedList<Integer>();
    //这里尝试一下用静态变量存储所有已经创建的LinkedListClass实例,
    //豆包ai说这个会有泄露的风险，想了一想缺失，类变量没有销毁这个内存怎么办呢,手动销毁只能
    static ArrayList<LinkedListClass> instanceArr  = new ArrayList<LinkedListClass>();

    public Integer[] getSite() {
        return (Integer[]) site.toArray(new Integer[0]);
    }

    static LinkedListClass getIns() {
        LinkedListClass ins = new LinkedListClass();
        //这里进行修改了一下，每次存储的时候进行空地址判断
        if(LinkedListClass.instanceArr == null){
            LinkedListClass.instanceArr = new ArrayList<LinkedListClass>();
        }
        LinkedListClass.instanceArr.add(ins);
        return ins;
    }

    static void clearIns(){
        //知识点:**java的内存管理jvm会自动回收不被引用的目标，所以这里与其删除数组元素，不如把数组置空
        instanceArr = null;
    }

    static void printIns(){
        for (LinkedListClass ins :LinkedListClass.instanceArr){
            //知识点：LinkedList的toArray方法返回的是objet[]，无法强制转换Integer[]，解决方法是加一个参数
           Integer[] site =  ins.getSite();
           //这里打印的是地址
//           System.out.println(site.toString());
            System.out.println(Arrays.toString(site));
        }
    }

    private LinkedListClass(){

    }
    //在列表首尾添加元素，返回添加是否成功，重载指定位置的方法返回值为void
    public boolean addToLinkedList(int a) {
        return this.site.add(a);
    }

    //在列表尾部添加元素
    public void addToLinkedList(int a, boolean isLast) {
        if (isLast) {
            this.site.addLast(a);
        } else {
            addToLinkedList(a);
        }
    }

    //删除首位元素，返回被删除的元素
    public int removeList() {
        return this.site.removeFirst();
    }

    //删除末尾元素
    public void removeList(boolean last) {
        if (last) {
            this.site.removeLast();
        } else {
            removeList();
        }
    }

    //获取第一位元素，返回元素
    public int getToLinkedList() {
        return this.site.getFirst();
    }

    //获取最后一位元素
    public int getToLinkedList(boolean isLast) {
        if (isLast) {
            return this.site.getLast();
        } else {
            return getToLinkedList();
        }
    }

}

//tips：豆包牛逼